/*------------------------------------------------------------------------------
 * Copyright 2012 NCR Corporation
 *------------------------------------------------------------------------------
 * All revision information is updated automatically from source code control
 * change records - please do not manually edit.
 *------------------------------------------------------------------------------
 *
 * $LastChangedRevision:: 2123                                     $
 * $LastChangedBy:: rb250096                                       $
 * $LastChangedDate:: 2012-04-18 00:43:25 -0400 (Wed, 18 Apr 2012) $
 */

package com.ncr.nep.dashboardcore.utils.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;

import com.google.gwt.core.client.GWT;

/**
 * Utility class that provides convenience methods for generating URLs that
 * work with the NEP backend service URL hierarchy (API urls, resource URLs,
 * etc).
 *
 * @author rb250096
 * @version $Revision: 2123 $
 */
public class URLUtil {

    //--------------------------------------------------------------------------
    //
    //  Fields
    //
    //--------------------------------------------------------------------------

    /**
     * The partial path where GWT resources are served from relative to the
     * resource dispatcher servlet URL.
     */
    public static String resourcePath = "resources/gwt";

    /**
     * The partial path where REST API calls stem from.
     */
    public static String apiPath = "api";

    /**
     * For testing, this can be used to provide a host URL when not in
     * client mode; this won't be used at runtime.
     */
    public static String testHostBase;

    /**
     * Constant defining path delimiter for URLs.
     */
    private static final String PATH_DELIMITER = "/";

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     * Gets the root URL for the host that is serving the GWT application
     * (not including module name in path).
     *
     * @return The URL of the base host.
     */
    public static String getHostBase() {
        String base = null;
        if(GWT.isClient()) {
            base = GWT.getModuleBaseURL().replace(GWT.getModuleName(), "");
        }
        else {
            base = testHostBase;
        }

        return stripSlashes(base.replace(resourcePath, ""));
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Determines if the specified URL contains a protocol declaration.
     *
     * @param url The URL to test.
     *
     * @return True if the URL starts with a protocol declaration.
     */
    public static boolean urlHasProtocol(String url) {
        return url != null &&
                (url.startsWith("http://") || url.startsWith("https://"));
    }

    /**
     * Generates a resource URL for resources served from the dispatcher
     * servlet on the backend.
     *
     * @param tokens 1 or more strings containing path elements to append
     *               to the final URL.
     *
     * @return The URL of the resource.
     */
    public static String generateResourceURL(String ...tokens) {
        if(tokens.length == 0) {
            return "";
        }

        List<String> t = new ArrayList<String>(Arrays.asList(tokens));
        t.add(0, resourcePath);
        return generateURL(getHostBase(), t);
    }

    /**
     * Generates an API URL for REST endpoints that are rooted at a common
     * URL path.
     *
     * @param tokens 1 or more strings containing path elements to append
     *               to the final URL.
     *
     * @return The API URL.
     */
    public static String generateApiURL(String ...tokens) {
        if(tokens.length == 0) {
            return "";
        }

        List<String> t = new ArrayList<String>(Arrays.asList(tokens));
        t.add(0, apiPath);
        return generateURL(getHostBase(), t);
    }

    /**
     * Generates URL using the provided base and set of partial path elements.
     *
     * @param hostBase The base URL of the host.
     * @param tokens 1 or more partial path elements to append to the final URL.
     *
     * @return The generated URL.
     */
    public static String generateURL(String hostBase, List<String> tokens) {
        tokens = new ArrayList<String>(tokens);
        tokens.add(0, hostBase);
        for(ListIterator<String> it = tokens.listIterator(); it.hasNext();) {
            String token = it.next();
            it.set(stripSlashes(token));
        }

        return StringUtil.join(PATH_DELIMITER, tokens);
    }

    /**
     * Removes starting and ending slashes from a portion of a URL.
     *
     * @param token The URL token to remove the start and/or end slashes.
     */
    public static String stripSlashes(String token) {
        if(token == null) return null;

        int startIndex = token.startsWith(PATH_DELIMITER) ? 1 : 0;
        int endIndex = token.length();
        for(int i = token.length() - 1; i >= 0; i--) {
            char c = token.charAt(i);
            if(c == PATH_DELIMITER.charAt(0)) {
                endIndex -= 1;
            }
            else {
                break;
            }
        }

        return token.substring(startIndex, endIndex);
    }
}
